﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>Introduction - 介绍</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
	</head>

	<body>

		<div class="document-contents">

			<h3 id="DocIntro">Introduction - 介绍</h3>
			<p>We are creating different applications based on different needs. 
But implementing common and similar structures over and over again, at 
least in some level. <strong>Authorization</strong>, <strong>Validation</strong>, 
				<strong>Exception Handling</strong>, <strong>Logging</strong>, <strong>Localization</strong>, 
				<strong>Database Connection Management</strong>, <strong>Setting Management</strong>, 
				<strong>Audit Logging</strong> are some of these common structures. Also, we 
are building <strong>architectural structures</strong> and <strong>best practices</strong> like
				<strong>Layered </strong>and <strong>Modular </strong>Architecture, <strong>Domain Driven Design</strong>, 
				<strong>Dependency Injection </strong>and so on. And trying to 
develop applications based on some <strong>conventions</strong>.</p>
			<p class="translation">
				我们总是基于不同的需求创建不同的应用，但是在一定程度上，总在反复地实现通用而相似的结构。
				这些通用的结构包括<strong>授权</strong>，<strong>验证</strong>，<strong>异常处理</strong>，
				<strong>日志</strong>，<strong>本地化</strong>，<strong>数据库连接管理</strong>，
				<strong>设置管理</strong>，<strong>审计日志</strong>等。
				而且，我们总是在构建<strong>体系结构</strong>和<strong>最佳实践</strong>，比如<strong>分层</strong>和<strong>模块化</strong>架构，
				<strong>领域驱动设计（DDD）</strong>，<strong>依赖注入</strong>等等。同时也在尝试基于<strong>惯例</strong>开发应用。

			</p>
			<p>Since all of these are very time-consuming and hard to build seperately for 
every project, many companies 
create private <strong>frameworks</strong>. They're developing new applications 
faster with less bugs using these frameworks. Surely, not all companies that 
lucky. Most of them have no <strong>time</strong>, <strong>budget</strong> and
				<strong>team</strong> to develop such frameworks. Even they have possibility to 
create a framework, it's hard to <strong>document</strong>, <strong>train 
developers</strong> and <strong>maintain</strong> it.</p>
			<p class="translation">
				因为这些都是非常耗时的，并且对于每个项目单独创建是很困难的，所以很多公司都会创建自己私有的<strong>框架</strong>。
				通过使用私有的框架，他们总是可以快速地开发新的应用，同时应用的bug又会更少。
				当然了，不是所有的公司都是那么幸运了。大多数公司还是没有<strong>时间</strong>，<strong>预算</strong>和<strong>团队</strong>来开发他们自己的私人框架。
				即使他们有可能构建这么一个框架，写<strong>文档</strong>，<strong>培训开发者</strong>以及<strong>维护</strong>也是很难的。
			</p>

			<p>ASP.NET Boilerplate (ABP) is an <strong>open source and well documented 
application framework </strong>started idea of "developing a <strong>common
				</strong>framework for all companies and all developers!" It's not just a 
framework but also provides a strong <strong>architectural model</strong> based 
on <strong>Domain Driven Design</strong> and <strong>best practices</strong> in 
mind.</p>
			<p class="translation">
				ASP.NET Boilerplate（ABP）是一个<strong>开源的且文档友好的应用程序框架</strong>，最初的想法是，“开发一款为所有公司和开发者<strong>通用</strong>的框架！”。
				它不仅仅是一个框架，更提供了一个基于<strong>领域驱动设计</strong>和<strong>最佳实践</strong>的健壮的<strong>体系模型</strong>。
			</p>

			<h3 id="DocQuickSample">A Quick Sample - 入门示例</h3>
			<p>Let's investigate a simple class to see ABP's benefits:</p>
			<p class="translation">让我们一起来研究一个简单的类来看看ABP有哪些好处 ：</p>
			<pre lang="cs">public class TaskAppService : ApplicationService, ITaskAppService
{
    private readonly IRepository&lt;Task&gt; _taskRepository;

    public TaskAppService(IRepository&lt;Task&gt; taskRepository)
    {
        _taskRepository = taskRepository;
    }

    [AbpAuthorize(MyPermissions.UpdatingTasks)]
    public async Task UpdateTask(UpdateTaskInput input)
    {
        Logger.Info(&quot;Updating a task for input: &quot; + input);

        var task = await _taskRepository.FirstOrDefaultAsync(input.TaskId);
        if (task == null)
        {
            throw new UserFriendlyException(L(&quot;CouldNotFoundTheTask<span lang="tr">Message</span>&quot;));
        }

        input.MapTo(task);
    }
}</pre>
			<p>Here, we see a sample <a href="/Pages/Documents/Application-Services">
Application Service</a> method. An application service, in DDD, is directly used 
by presentation layer to perform <strong>use cases</strong> of the application. 
We can think that <strong>UpdateTask </strong>method is called by javascript via 
AJAX. Let's see ABP's some benefits here:</p>
			<p class="translation">
				这里我们看到了一个简单的<a href="/Pages/Documents/Application-Services">应用服务</a>方法。
				在 DDD 中，表现层直接使用应用服务来执行该应用的<strong>用例</strong>。
				我们还可以考虑使用 Ajax 调用上面的 UpdateTask 方法。
				下面让我们看一下 ABP 的一些优点：
			</p>
			<ul>
				<li>
					<strong>
						<a href="/Pages/Documents/Dependency-Injection">Dependency 
	Injection</a>
					</strong>: ABP uses and provides a strong and conventional DI 
	infrastructure. Since this class is an application service, it's 
	conventionally registered to DI container as transient (created per 
	request). It can simply inject all dependencies (as IRepository&lt;Task&gt; in 
	this sample).
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Dependency-Injection">依赖注入</a></strong>:
					ABP使用并提供了一个健壮且依照惯例的 DI 基础设施。因为上面的类是在一个应用服务，所以它会依照惯例以瞬时（每个请求创建一次）方法注册到 DI 容器中。
					它可以简单的注入了所有依赖（本例中注入了 IRepository&lt;Task&gt;）。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Repositories">Repository</a>
					</strong>: 
	ABP can create a default repository for each entity (as IRepository&lt;Task&gt; in 
	this example). Default repository has many useful methods as FirstOrDefault 
	used in this example. We can easily extend default repository upon our 
	needs. Repositories abstracts DBMS and ORMs and simplifies data access 
	logic.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Repositories">仓库</a></strong>: 
					ABP 可以为每一个实体创建一个默认的仓库（本例中是 IRepository&lt;Task&gt;）。
					默认的仓库有许多有用的方法，如本例中的 FirstOrDefault。
					我们也可以根据我们的需求轻易地扩展默认仓库。
					仓库抽象了 DBMS 和 ORM，并简化了数据的访问逻辑。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Authorization">Authorization</a>
					</strong>: 
	ABP can check permissions. It prevents access to UpdateTask method if 
	current user has no "updating task" permission or not logged in. It 
	simplifies authorization using declarative attributes but also has 
	additional ways of authorization.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Authorization">授权</a></strong>:
					ABP 可以检测权限。如果当前的用户没有“updating task”的权限或者未登录，那么它不能访问 UpdateTask 方法。
					它使用声明式的特性简化了授权，并且还有其他的授权方法。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Validating-Data-Transfer-Objects">
	Validation</a>
					</strong>: ABP automatically checks if input is null. It also 
	validates all properties of an input based on standard data annotation 
	attributes and custom validation rules. If request is not valid, it throws a 
	proper validation exception.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Validating-Data-Transfer-Objects">验证</a></strong>:
					ABP 会自动检测输入是否为 null。它也基于标准的数据注解特性和自定义的验证规则验证输入对象的所有属性。
					如果请求不是有效的，那么它会抛出一个合适的验证异常。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Audit-Logging">Audit Logging</a>
					</strong>: 
	User, browser, IP address, calling service, method, parameters, calling 
	time, execution duration and some other informations are automatically saved 
	for each request based on conventions and configurations.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Audit-Logging">审计日志</a></strong>: 
					用户，浏览器，IP 地址，调用服务，方法，参数，调用时间，执行时长和其他的一些信息也会基于惯例和配置为每个请求自动地保存。
				</p>
				<li>
					<a href="/Pages/Documents/Unit-Of-Work">
						<strong>Unit Of Work</strong>
					</a>: 
	In ABP, each application service method is assumed as a unit of work as 
	default. It automatically creates a connection and begins a transaction at 
	the beggining of the method. If the method successfully completed without 
	exception, then the transaction is commited and connection is disposed. Even 
	this method uses different repositories or methods, all of them will be 
	atomic (transactional). And all changes on entities are automatically saved 
	when transaction is commited. Thus, we don't even need to call 
	_repository.Update(task) method as shown here.
				</li>
				<p class="translation">
					<a href="/Pages/Documents/Unit-Of-Work"><strong>工作单元</strong></a>: 
					在 ABP 中，每个应用服务方法默认情况下被视为一个工作单元。
					在方法的开始位置会自动创建一个连接开启一个事务。
					如果方法不报异常地成功完成了，那么事务会提交并且连接被释放。
					即使该方法使用了不同的仓库或方法，它们全部也都是原子的（事务的）。
					当事务提交时，实体的所有改变都会自动保存。
					因此，正如这里展示的那样，我们甚至都不用调用 _repository.Update(task) 方法。
				</p>
				<li>
					<a href="/Pages/Documents/Handling-Exceptions">
						<strong>Exception 
	Handling</strong>
					</a>: We almost never handle exceptions in ABP in a web 
	application. All exceptions are automatically handled by default. If an 
	exception occurs, ABP automatically logs it and returns a proper result to 
	the client. For example, if this is an AJAX request, the it returns a JSON 
	to client indicates that an error occured. If hides actual exception from 
	client unless the exception is a UserFriendlyException as used in this 
	sample. It also understands and handles errors on client side and show 
	appropriate messages to users.
				</li>
				<p class="translation">
					<a href="/Pages/Documents/Handling-Exceptions"><strong>异常处理</strong></a>: 
					在一个使用了 ABP 框架的 Web 应用中，我们基本上不用处理异常。
					所有的异常在默认情况下都会自动处理。
					如果一个异常发生了，那么 ABP 会自动地记录它，然后返回给客户端一个合适的结果。
					比如，如果这是一个 Ajax 请求，那么它会返回一个 JSON 到客户端，指明发生了一个错误。
					本例中使用了一个 UserFriendlyException，这样就为客户端隐藏了实际的异常信息。
					它同样可以在客户端理解并处理错误，最后将合适的信息呈现给用户。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Logging">Logging</a>
					</strong>: As you 
	see, we can write logs using the Logger object defined in base class. 
	Log4Net is used as default but it's changable or configurable.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Logging">日志</a></strong>:
					你可以看到我们可以使用在基类中定义的 Logger 对象来记录日志。ABP 默认使用了 Log4Net，但是它是可更改或可配置的。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Localization">Localization</a>
					</strong>: 
	Notice that we used L method while throwing exception. Thus, it's 
	automatically localized based on current user's culture. Surely, we're 
	defining CouldNotFoundTheTask<span lang="tr">Message </span>in somewhere 
	(see <a href="/Pages/Documents/Localization">localization</a> document for more).
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Localization">本地化</a></strong>: 
					注意当抛出异常的时候我们使用了 L 方法。因此，它会基于当前用户的文化自动进行本地化。
					当然，我们可以在某些地方定义 CouldNotFoundTheTask<span lang="tr">Message</span>（更多内容参阅<a href="/Pages/Documents/Localization">本地化</a>文档）。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Data-Transfer-Objects">Auto Mapping</a>
					</strong>: 
	In the last line, we're using ABP's MapTo extension method to map input 
	properties to entity properties. It uses AutoMapper library to perform 
	mapping. Thus, we can easily map properties from one object to another based 
	on naming conventions.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Data-Transfer-Objects">自动映射</a></strong>: 
					上面的最后一行代码，我们使用了 ABP 的 MapTo 扩展方法将输入对象的属性映射到实体属性。
					它使用 AutoMapper 库来执行映射。因此，我们可以基于命名惯例轻易地将属性从一个对象上映射到另一个对象上。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Dynamic-Web-API">Dynamic Web API Layer</a>
					</strong>: 
	TaskAppService is a simple class actually (even no need to deliver from 
	ApplicationService). We generally write a wrapper Web API Controller to 
	expose methods to javascript clients. ABP automatically does that on 
	runtime. Thus, we can use application service methods directly from clients.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Dynamic-Web-API">动态 Web API 层</a></strong>: 
					实际上，TaskAppService 是一个简单的类（甚至不需要从 ApplicationService 派生）。
					我们一般会写一个 Web API Controller 包装器来将方法公开给 javascript 客户端。
					ABP 会在运行时自动完成。这样，我们可以从客户端直接使用应用服务方法。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Dynamic-Web-API#DocDynamicProxy">
	Dynamic Javascript AJAX Proxy</a>
					</strong>: ABP creates javascript proxy 
	methods those make calling application service methods just as simple as 
	calling javascript methods on the client.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Dynamic-Web-API#DocDynamicProxy">动态 Javascript AJAX 代理</a></strong>：
					ABP 创建了 javascript 代理方法，它们可以调用应用服务方法就像调用客户端的 javascript 方法一样简单。
				</p>
			</ul>
			<p>We can see benefit of ABP in such a simple class. All these tasks normally 
take significiant time, but all they are automatically handled by ABP.</p>
			<p class="translation">在这么一个简单的类中，我们看到了 ABP 的优势。所有的这些任务正常情况下都是要花费很多时间的，但是所有的这些 ABP 自动帮我们完成了。</p>

			<h3 id="DocWhatElse">What Else - 还有别的吗</h3>
			<p>Beside this simple example, ABP provides a strong infrastructure and 
application model. Here, some other features of ABP:</p>
			<p class="translation">除了这个简单的例子，ABP也提供了一个健壮的基础设施和应用程序模型。下面是 ABP 的一些其他特征：</p>
			<ul>
				<li>
					<strong>
						<a href="/Pages/Documents/Module-System">Modularity</a>
					</strong>: 
	Provides a strong infrastructure to build reusable modules.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Module-System">模块化</a></strong>：
					提供了一个健壮的基础设施来生成可复用的模块。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Data-Filters">Data Filters</a>
					</strong>: 
	Provides automatic data filtering to implement some patterns like 
	soft-delete and multi-tenancy.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Data-Filters">数据过滤器</a></strong>：
					提供了自动的数据过滤器来实现一些像软删除和多租户似的模式。
				</p>
				<li>
					<strong><a href="Multi-Tenancy.html">Multi Tenancy</a></strong>: It 
					fully supports multi-tenancy, including single database or 
					database per tenant architectures.
				</li>
				<p class="translation">
					<strong><a href="Multi-Tenancy.html">多租户</a></strong>：
					全面支持多租户，包含了单数据库或每租户一数据库的体系结构。
				</p>
				<li>
					<strong>
						<a href="/Pages/Documents/Setting-Management">Setting Management</a>
					</strong>: 
	Provides a strong infrastructure to get/change application, tenant and user 
	level settings.
				</li>
				<p class="translation">
					<strong><a href="/Pages/Documents/Setting-Management">设置管理</a></strong>：
					提供了健壮的基础设施来获得或更改应用程序，租户及用户级别的设置。
				</p>
				<li>
					<strong>Unit &amp; Integration Testing</strong>: It's built testability in 
	mind. Also provides base classes to simplify unit &amp; integration tests. See
					<a href="http://www.codeproject.com/Articles/871786/Unit-testing-in-Csharp-using-xUnit-Entity-Framewor">
	this article</a> for more information.
				</li>
				<p class="translation">
					<strong>单元 &amp; 集成测试</strong>：
					它在内部是基于可测试性构建的。同时提供了一些基类来简化单元测试和集成测试。
					更多信息参阅<a href="http://www.codeproject.com/Articles/871786/Unit-testing-in-Csharp-using-xUnit-Entity-Framewor">这篇文章</a>。
				</p>
			</ul>
			<p>For all features, see <a href="/Pages/Documents">documentation</a>.</p>
			<p class="translation">更多的特性，请阅读<a href="/Pages/Documents">文档</a>。</p>

			<h3 id="DocStartupTemplate">Startup Templates - 启动模板</h3>
			<p>Starting a new solution, creating layers, installing nuget packages, creating 
a simple layout and a menu... all these are also time consuming stuff.</p>
			<p class="translation">开始一个新的解决方案，创建层，安装 nuget 包，创建一个简单的布局和菜单...所有的这些都是非常耗时的。</p>
			<p>ABP provides pre-built
				<a href="http://www.aspnetboilerplate.com/Templates">startup templates</a> that 
makes starting a new solution is much more easier. Templates support <strong>SPA</strong> 
(Single-Page Application) and <strong>MPA</strong> (Multi-Page MVC Applications) 
architectures. Also, allows us to use different ORMs.</p>
			<p class="translation">ABP 提供了一个预生成的<a href="http://www.aspnetboilerplate.com/Templates">启动模板</a>，使得创建一个新的解决方案更容易了。
				模板支持 <strong>SPA</strong>（单页应用）和 <strong>MPA</strong>（多页应用）。而且，我们可以选择不同的 ORM。</p>

			<h3 id="DocHowToUse">How To Use - 如何使用</h3>
			<p>ABP is developed on <strong>
					<a href="https://github.com/aspnetboilerplate">Github</a>
				</strong> and 
distributed on <strong>
					<a href="/Pages/Documents/Nuget-Packages">Nuget</a>
				</strong>. 
Easiest way of starting with ABP is creating a
				<a href="http://www.aspnetboilerplate.com/Templates">startup template</a> and 
following the <a href="/Pages/Documents">documentation</a>.</p>
			<p class="translation">ABP 的源码已经推送到了 <strong><a href="https://github.com/aspnetboilerplate">Github</a></strong> 上，
				Nuget包也已经发布到了 <strong><a href="/Pages/Documents/Nuget-Packages">Nuget</a></strong> 上。
				开始使用 ABP 最简单的方式就是使用 ABP 官网的<a href="http://www.aspnetboilerplate.com/Templates">启动模板</a>创建项目，然后跟着<a href="/Pages/Documents">文档</a>进行学习。</p>
		</div>
	</body>

</html>
